package com.ndp.fb.scheduler.job.business;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.ndp.fb.config.ConfigCentre;
import com.ndp.fb.constant.ConfigConst;
import com.ndp.fb.data.api.service.schedulerservice.statitics.AdMarketTargetStatsService;
import com.ndp.fb.data.api.service.schedulerservice.statitics.AdResourceStatsService;
import com.ndp.fb.data.api.service.schedulerservice.statitics.AdSetStatsService;
import com.ndp.fb.data.api.service.schedulerservice.statitics.FBAdGroupStatsService;
import com.ndp.fb.mongo.api.AdMarketTargetMongoService;
import com.ndp.fb.rdb.api.EntrustAccountRdbService;
import com.ndp.fb.rdb.model.EntrustAccount;
import com.ndp.fb.mongo.model.autocreatead.AdMarketTarget;
import com.ndp.fb.scheduler.annotation.CronScheduled;
import com.ndp.fb.util.ThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * Created by Evan on 2015/3/5 15:38.
 */
@Component
public class StatsFetchJob {
    private static Logger logger = LoggerFactory.getLogger(StatsFetchJob.class);

    @Reference
    EntrustAccountRdbService accountRdbService;
    @Reference
    AdSetStatsService adSetStatsService;
    @Reference
    AdResourceStatsService adResourceStatsService;
    @Reference
    FBAdGroupStatsService adGroupStatsService;
    @Reference
    AdMarketTargetMongoService adMarketTargetRdbService;
    @Reference
    AdMarketTargetStatsService adMarketTargetStatsService;

    /**
     * 以天为单位计算adset的增量统计数据调度
     */
    @CronScheduled(cronkey = ConfigConst.SCHEDULE_ADSET_STATS_INCREMENT_CRON, enablekey = ConfigConst.SCHEDULE_ADSET_STATS_INCREMENT_ENABLE)
    public void calAdSetStatsIncrement() {
        logger.info("以天为单位计算adset的增量统计数据调度开始");
        ThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                List<EntrustAccount> entrustAccounts = accountRdbService.findAllAdAccount();
                for (final EntrustAccount entrustAccount : entrustAccounts) {
                    try {
                        adSetStatsService.calAdSetStatsByAccountAndDay(entrustAccount, 0);
                    } catch (Exception e) {
                        logger.error("以天为单位计算adset的增量统计数据调度出错", e);
                    }
                }
            }
        });
    }

    /**
     * 计算adset的延时转化数据
     */
    @CronScheduled(cronkey = ConfigConst.SCHEDULE_ADSET_STATS_DELAYED_CRON, enablekey = ConfigConst.SCHEDULE_ADSET_STATS_DELAYED_ENABLE)
    public void calAdSetStatsStatsDelayed() {
        logger.info("以天为单位计算adset延时转化统计数据调度开始");
        ThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                int delayedDay = ConfigCentre.getInteger(ConfigConst.ADGROUP_DELAYED_DAYS);
                List<EntrustAccount> entrustAccounts = accountRdbService.findAllAdAccount();
                logger.info("以天为单位计算adset延时转化统计数据调度，总共需要处理{}天", delayedDay);
                for (final EntrustAccount entrustAccount : entrustAccounts) {
                    try {
                        adSetStatsService.calAdSetStatsByAccountAndDay(entrustAccount, delayedDay);
                    } catch (Exception e) {
                        logger.error("以天为单位计算adset延时转化统计数据调度出错", e);
                    }
                }
            }
        });
    }

    /**
     * 以天为单位计算素材的增量统计数据调度
     */
    @CronScheduled(cronkey = ConfigConst.SCHEDULE_ADRESOURCE_STATS_INCREMENT_CRON, enablekey = ConfigConst.SCHEDULE_ADRESOURCE_STATS_INCREMENT_ENABLE)
    public void calAdResourceStatsIncrement() {
        logger.info("以天为单位计算素材的增量统计数据调度开始");
        ThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                List<EntrustAccount> entrustAccounts = accountRdbService.findAllAdAccount();
                for (final EntrustAccount entrustAccount : entrustAccounts) {
                    try {
                        adResourceStatsService.calAdResourceStatsByAccountAndDay(entrustAccount, 0);
                    } catch (Exception e) {
                        logger.error("以天为单位计算素材的增量统计数据调度出错", e);
                    }
                }
            }
        });
    }

    /**
     * 以天为单位计算素材的延迟统计数据调度
     */
    @CronScheduled(cronkey = ConfigConst.SCHEDULE_ADRESOURCE_STATS_DELAYED_CRON, enablekey = ConfigConst.SCHEDULE_ADRESOURCE_STATS_DELAYED_ENABLE)
    public void calAdResourceStatsDelayed() {
        logger.info("以天为单位计算素材的延迟统计数据调度开始");
        ThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                int delayedDay = ConfigCentre.getInteger(ConfigConst.ADRESOURCE_DELAYED_DAYS);
                List<EntrustAccount> entrustAccounts = accountRdbService.findAllAdAccount();
                logger.info("以天为单位计算素材的延迟统计数据调度，总共需要处理{}天", delayedDay);
                for (final EntrustAccount entrustAccount : entrustAccounts) {
                    try {
                        adResourceStatsService.calAdResourceStatsByAccountAndDay(entrustAccount, delayedDay);
                    } catch (Exception e) {
                        logger.error("以天为单位计算素材的延迟统计数据调度出错", e);
                    }
                }
            }
        });
    }

    /**
     * 创建今日AdGroup统计数据计算异步Job调度
     */
    @CronScheduled(cronkey = ConfigConst.SCHEDULE_STATS_CREATE_TODAY_ASYNC_JOB_CRON, enablekey = ConfigConst.SCHEDULE_STATS_CREATE_TODAY_ASYNC_JOB_ENABLE)
    public void createTodayAsynchronousJob() {
        logger.info("创建今日AdGroup统计数据计算异步Job调度开始");
        ThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                List<String> breakdowns = JSON.parseObject(ConfigCentre.getString(ConfigConst.ADGROUP_BREAKDOWNS), List.class);
                List<EntrustAccount> entrustAccounts = accountRdbService.findAdAccountListByRoles("ADMIN", "GENERAL_USER", "REPORTS_ONLY");
                for (final EntrustAccount entrustAccount : entrustAccounts) {
                    for (String breakdown : breakdowns) {
                        try {
                            adGroupStatsService.createAsynchronousJob(entrustAccount, 0, breakdown);
                        } catch (Exception e) {
                            logger.error("创建账号{}今日AdGroup的{}统计数据计算异步Job调度调度出错", entrustAccount.getFbAccountId(), breakdown, e);
                        }
                    }
                }
            }
        });
    }

    /**
     * 创建今日AdGroup统计数据计算异步Job调度
     */
    @CronScheduled(cronkey = ConfigConst.SCHEDULE_STATS_CREATE_DELAY_ASYNC_JOB_CRON, enablekey = ConfigConst.SCHEDULE_STATS_CREATE_DELAY_ASYNC_JOB_ENABLE)
    public void createDelayAsynchronousJob() {
        logger.info("创建延迟AdGroup统计数据计算异步Job调度开始");
        ThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                int delayedDay = ConfigCentre.getInteger(ConfigConst.ADGROUP_DELAYED_DAYS);
                List<String> breakdowns = JSON.parseObject(ConfigCentre.getString(ConfigConst.ADGROUP_BREAKDOWNS), List.class);
                List<EntrustAccount> entrustAccounts = accountRdbService.findAdAccountListByRoles("ADMIN", "GENERAL_USER", "REPORTS_ONLY");
                logger.info("创建延迟AdGroup统计数据计算异步Job调度，总共需要处理{}天", delayedDay);
                for (final EntrustAccount entrustAccount : entrustAccounts) {
                    for (int i = 1; i <= delayedDay; i++) {
                        for (String breakdown : breakdowns) {
                            try {
                                adGroupStatsService.createAsynchronousJob(entrustAccount, -i, breakdown);
                            } catch (Exception e) {
                                logger.error("创建账号{}的{}天前AdGroup的{}统计数据计算异步Job调度出错", entrustAccount.getFbAccountId(), i, breakdown, e);
                            }
                        }
                    }
                }
            }
        });
    }

    /**
     * 获取AdGroup统计数据计算异步Job状态调度
     */
    @CronScheduled(cronkey = ConfigConst.SCHEDULE_STATS_GET_ASYNC_JOB_STATUS_CRON, enablekey = ConfigConst.SCHEDULE_STATS_GET_ASYNC_JOB_STATUS_ENABLE)
    public void getAsynchronousJobStatus() {
        logger.info("获取AdGroup统计数据计算异步Job状态调度开始");
        ThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                List<EntrustAccount> entrustAccounts = accountRdbService.findAdAccountListByRoles("ADMIN", "GENERAL_USER", "REPORTS_ONLY");
                for (final EntrustAccount entrustAccount : entrustAccounts) {
                    try {
                        adGroupStatsService.getAsynchronousJobStatus(entrustAccount);
                    } catch (Exception e) {
                        logger.error("创建账号{}今日AdGroup统计数据计算异步Job调度调度出错", entrustAccount.getFbAccountId(), e);
                    }
                }
            }
        });
    }

    /**
     * 以天为单位计算素材的统计数据（只包含新创建广告）调度
     */
    @CronScheduled(cronkey = ConfigConst.SCHEDULE_ADRESOURCE_STATS_NEWAD_CRON, enablekey = ConfigConst.SCHEDULE_ADRESOURCE_STATS_NEWAD_ENABLE)
    public void calAdResourceStatsForNewAd() {
        logger.info("以天为单位计算素材的增量统计数据调度开始");
        ThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                List<EntrustAccount> entrustAccounts = accountRdbService.findAllAdAccount();
                for (final EntrustAccount entrustAccount : entrustAccounts) {
                    try {
                        adResourceStatsService.calAdResourceStatsForNewAd(entrustAccount);
                    } catch (Exception e) {
                        logger.error("以天为单位计算素材的增量统计数据调度出错", e);
                    }
                }
            }
        });
    }

    /**
     * 计算用户的素材流水存入用户表
     */
    @CronScheduled(cronkey = ConfigConst.SCHEDULE_ADRESOURCE_STATS_USER_CRON, enablekey = ConfigConst.SCHEDULE_ADRESOURCE_STATS_USER_ENABLE)
    public void calAdResourceStatsForUser() {
        logger.info("计算用户的素材统计数据调度开始");
        ThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                adResourceStatsService.calAdResourceStatsForUser();
            }
        });
    }

    /**
     * 计算营销目标统计数据
     */
    @CronScheduled(cronkey = ConfigConst.SCHEDULE_AD_MARKET_TARGET_STATS_USER_CRON, enablekey = ConfigConst.SCHEDULE_AD_MARKET_TARGET_STATS_USER_ENABLE)
    public void calAdMarketTargetStats() {
        logger.info("计算营销目标统计数据调度开始");
        ThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                List<AdMarketTarget> adMarketTargetList = adMarketTargetRdbService.getAllList();
                for (final AdMarketTarget adMarketTarget : adMarketTargetList) {
                    try {
                        adMarketTargetStatsService.calAdMarketTargetStatsByMarketId(adMarketTarget.getId());
                    } catch (Exception e) {
                        logger.error("计算营销目标统计数据调度出错", e);
                    }
                }
            }
        });
    }
}
